package com.zp.self.aop;

import com.zp.self.annotation.DBSelect;
import com.zp.self.多数据源工具.DynamicDataSourceContextHolder;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import java.util.Objects;

/**
 * TODO
 *
 * @author: mason
 * @since: 2020/1/9
 **/
@Aspect
@Component
public class DynamicDataSourceAspect {
    //切入点
    @Pointcut("@annotation(com.zp.self.annotation.DBSelect)")
    public void dataSourcePointCut(){

    }

    //环切，设置线程变量
    @Around("dataSourcePointCut()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        String dsKey;
        //查找类上是否有DBSelect注解
        Class<?> targetClass = joinPoint.getTarget().getClass();
        DBSelect dsAnnotation = targetClass.getAnnotation(DBSelect.class);
        // 先判断类的注解，再判断方法注解
        if(Objects.nonNull(dsAnnotation)){
            dsKey =  dsAnnotation.value();
        }else{
            //查找方法上是否有DBSelect注解
            MethodSignature methodSignature = (MethodSignature)joinPoint.getSignature();
            dsKey = methodSignature.getMethod().getAnnotation(DBSelect.class).value();
        }

        //设置线程变量：数据源key  ；动态数据源通过此变量获取相应数据源
        DynamicDataSourceContextHolder.setContextKey(dsKey);
        try{
            return joinPoint.proceed();
        }finally {
            DynamicDataSourceContextHolder.removeContextKey();
        }
    }
}
